#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <time.h>
#include "param.h"
#include "legoland.h"
#include "frequency.h"
#include "kmeans.h"
#include "createREF2.h"
#include "analyzeREADS.h"

using namespace std;

bool print_intro(int & r);
bool merge();


/**
DISCO v1.something: lots of changes by Mike Shaffer (skiman101@gmail.com) over the course of summer '13.  His latest code is stored at
https://code.google.com/p/disco-comp-bio/ pulls are free and access to changes at request, changes for Zach's latest include: removal
of kmeans clustering, multiple changes from arrays to vectors, creation of references from individual files as opposed to file of files
followed by merging into larger librares, many errors removed as well as added.  Good Luck! Here are some TODO's:
-resolution of taxa problem
-figuring out sensitivity of legoland
-adding error checking for some regions
-spelling and user interface stuff
-moving to server based processing and GUI
-figure out naming of libraries for individual genomes
**/

int main()      //for testing
{
//    int i=0;
//
//    while(i!=3)
//    {
//        print_intro(i);
//        if(i==1)
//        {
//            CreateREF2 * c=new CreateREF2();
//            delete c;
//        }
//        else if (i==2)
//        {
//            analyzeREADS * a=new analyzeREADS();
////            a->generate_output_files();
//            delete a;
//        }
//    }
    merge();
}





/*************************************************************************
* print_intro - prints welcome and first options for user
*   parameters:
*       -r: option selected by user.
*   return: true
**************************************************************************/
bool print_intro(int & r)
{
    bool loop=true;
    system("CLS");
    cout << "Welcome to DISCO v1.0!" << endl;
    while(loop)
    {
        cout << "Would you like to:\n";
        cout << "1 -> Create a new reference library" << endl;
        cout << "2 -> Analyze reads using an existing library" << endl;
        cout << "3 -> Quit" << endl;
        cout << "Enter choice 1 or 2 or 3: ";
        cin >> r;
        if( (r==1) || (r==2) || (r==3) ) loop=false;
        else cout << "That is not a valid choice. Try again.\n";
    }
    return true;
}


/*
int main__real()
{
    int i,j;
    Param * p;
    p=new Param();
    int num_coordinates;
    kmeans * clusters;
    int kum=100;            //just a test value

    //if new reference set has to be created


    //else run
 //   p->load_taxa();               //create taxa look up table
    legoland ** l=new legoland * [p->k_max-p->k_min+1];
    for(i=p->k_min; i<=p->k_max; i++)
    {
        l[i]=new legoland();

        for(j=0; j<p->num_reference_sp; j++)
        {
            centroid * plot=NULL;
            coordinates * data=NULL;
            Profile * profile=new Profile(i,p->r,p->gc_dim1_file,p->gc_dim2_file);
            num_coordinates=profile->get_coordinates_genome(p->reference_set,j,data);
            clusters=new kmeans(num_coordinates, data, kum);
            clusters->execute(plot);
//            l[i]->add(j,plot);                                                                                                  //problem. vector to array.
        }

    }

}
*/
/**
possibly make its own class
need to figure out genus/species/taxa stuff
merges genome libraries into one larger library
largely untested, errors presist
**/
bool merge()
{
    //initialize, get params
    int readSize, mult, kmin, kmax, kmintemp, kmaxtemp, readSizetemp, axes1, axes2, tempaxes1, tempaxes2, i, j;
    string name;
    vector<string> taxa;
    cout << "Enter name for megaLibrary: ";
    cin >> name;
    cout << "Enter desired read size for library: ";
    cin >> readSize;
    cout << "Enter desired multiplier for library: ";
    cin >> mult;
    cout << "Enter desired minimum k-size for library: ";
    cin >> kmin;
    cout << "Enter desired maxiumum k-size for library: ";
    cin >> kmax;
    cout << "Enter desired x axis: ";
    cin >> axes1;
    cout << "Enter desired y axis: ";
    cin >> axes2;
    centroid tempCent;
    vector<centroid> cents;
    legoland legos [kmax-kmin];
    bool thing = true;
    string fileName;
    fstream in;
    char line [100];

    while (thing == true)
    {
        cout << "enter a damn library or q" << endl;
        cin >> fileName;
        if (fileName=="q")
        {
            thing = false;
            cout << "goodbye" << endl;
            continue;
        }
        in.open(fileName.c_str());
        if (!in.is_open())
        {
            cout << "no such library found" << endl;
            continue;
        }
        in >> kmintemp;
        in >> kmaxtemp;
        in >> tempaxes1;
        in >> tempaxes2;
        in >> readSizetemp;
        if (readSize != readSizetemp)
        {
            cout << "different read sizes" << endl;
            continue;
        }
        if (axes1 != tempaxes1 || axes2 != tempaxes2)
        {
            cout << "different axes" << endl;
            continue;
        }
        if (kmin != kmintemp || kmax != kmaxtemp)
        {
            cout << "no useful k sizes" << endl;
            continue;
        }
        for (int i = 0; i < kmax-kmin; i++)
        {
            while (in.peek()!='*')
            {
                cin >> tempCent.x;
                cin >> tempCent.y;
                cin >> tempCent.prob;
                tempCent.prob = tempCent.prob*1000000000;
                cents.push_back(tempCent);
            }
            legos[i].add(taxa.size(), cents);
            taxa.push_back(fileName);
            cents.clear();
        }
        in.clear();
        in.close();
    }

    //print to library
    //write out to file
    ofstream out;
    char file[300];
    sprintf(file,"%s_disco.lib",name.c_str());
    out.open(file);
    if (!out.is_open())
    {
        cout << "library destination file not opened" << endl;
        return false;
    }
    cout << "file opened" << endl;
    out << kmin << "\t" << kmax << endl;
    out << axes1 << "\t" << axes2 << endl;
    out << readSize << endl << legos[0].get_multiplier() << endl;
    out << taxa.size() << endl;
    for( i=0; i<taxa.size(); i++)
        out << taxa[i] << "\t";
    out << taxa[i] << endl;
    out << "*" << endl;
    vector<lego> v;
//    unsigned long long ii;
    for(i=0; i<kmax-kmin; i++)
    {
        for(int x=0; x<mult+1; x++)
        {
            for (int y=0; y<mult+1; y++)
            {
                v=legos[i].search(x,y);
                if(v.size()!=0)
                {
                    out << x << "\t" << y << "\t" << v.size() << "\t";
                    for(j=0; j<v.size()-1; j++)
                        out << v[j].taxon << "\t" << v[j].prob << "\t";
                    out << v[j].taxon << "\t" << v[j].prob << endl;
                }
            }
        }
        legos[i].printLegoland();
        out << "*";
        cout << "about to delete l[i]" << endl;
        legos[i] = NULL;
        cout << "l[i] deleted" << endl;           //cleaning memory as i write
    }
    out.clear();
    out.close();


    //clean up memory
    delete legos;

    return true;
}
